use axum::{routing::post, Router};
use serde::Deserialize;

use crate::{error::AppErr, serialport::{self, address, cmd}, serve::utils::{Cbor, Void}};

async fn on_stir_cap_ctrl(ctrl: Cbor<u8>) -> Result<Void, AppErr> {
    serialport::req(
        address::HEAT,
        cmd::heat::STIR_CAP, 
        ctrl.0
    ).await?.res_result()?;
    Ok(Void)
}

async fn on_stir_motor_ctrl(ctrl: Cbor<u8>) -> Result<Void, AppErr> {
    serialport::simple_req(
        address::HEAT,
        cmd::heat::STIR_MOTOR,
        ctrl.0
    ).await?.res_result()?;
    Ok(Void)
}

#[derive(Deserialize)]
struct PartsCtrlReq {
    id: u8,
    ctrl: u8,
}

async fn on_parts_ctrl(req: Cbor<PartsCtrlReq>) -> Result<Void, AppErr> {
    serialport::simple_req(
        address::HEAT,
        cmd::heat::PARTS_CTRL,
        (req.id, req.ctrl)
    ).await?.res_result()?;
    Ok(Void)
}

async fn on_pearl_motor(req: Cbor<u32>) -> Result<Void, AppErr> {
    serialport::req(
        address::HEAT,
        cmd::heat::PEARL_MOTOR,
        req.0
    ).await?.res_result()?;
    Ok(Void)
}

pub fn register() -> Router {
    Router::new()
        .route("/stir_cap", post(on_stir_cap_ctrl))
        .route("/stir_motor", post(on_stir_motor_ctrl))
        .route("/parts_ctrl", post(on_parts_ctrl))
        .route("/pearl_motor", post(on_pearl_motor))
}



